import java.util.*;

import com.sun.jna.*;
import com.sun.jna.platform.win32.*;

public class Cyberslacking {
	static WinUser.HHOOK hhk1, hhk2;
	static WinUser.HOOKPROC proc1, proc2;
	static volatile boolean isRunning;

	public Cyberslacking(String... args) {
		proc1 = new WinUser.LowLevelKeyboardProc() {
			@Override
			public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wParam, WinUser.KBDLLHOOKSTRUCT lParam) {
				if (nCode == 0 && wParam.intValue() == WinUser.WM_KEYDOWN) {
					if (lParam.vkCode == 27) {// ESC
						isRunning = !isRunning;
					}
					if (isRunning) {
						showWindow(args);
					}
					System.out.println(lParam.toString());
				}
				return User32.INSTANCE.CallNextHookEx(hhk1, nCode, wParam, new WinDef.LPARAM(Pointer.nativeValue(lParam.getPointer())));
			}
		};

		proc2 = new WinUser.LowLevelMouseProc() {
			@Override
			public WinDef.LRESULT callback(int nCode, WinDef.WPARAM wParam, WinUser.MSLLHOOKSTRUCT lParam) {
				if (nCode == 0) {
					if (wParam.intValue() == 520) {// WM_MBUTTONUP
						isRunning = !isRunning;
					}
					if (isRunning && wParam.intValue() == 512) {// WM_MOUSEMOVE
						showWindow(args);
					}
					System.err.println(lParam.toString());
				}
				return User32.INSTANCE.CallNextHookEx(hhk2, nCode, wParam, new WinDef.LPARAM(Pointer.nativeValue(lParam.getPointer())));
			}
		};

		hhk1 = User32.INSTANCE.SetWindowsHookEx(User32.WH_KEYBOARD_LL, proc1, Kernel32.INSTANCE.GetModuleHandle(null), 0);
		hhk2 = User32.INSTANCE.SetWindowsHookEx(User32.WH_MOUSE_LL, proc2, Kernel32.INSTANCE.GetModuleHandle(null), 0);

		try {
			WinUser.MSG lpMsg = new WinUser.MSG();
			int bRet;
			while ((bRet = User32.INSTANCE.GetMessage(lpMsg, null, 0, 0)) != 0) {
				if (bRet == -1) {
					throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
				} else {
					User32.INSTANCE.TranslateMessage(lpMsg);
					User32.INSTANCE.DispatchMessage(lpMsg);
				}
			}
		} finally {
			try {
				if (!User32.INSTANCE.UnhookWindowsHookEx(hhk1)) {
					throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
				}
			} finally {
				if (!User32.INSTANCE.UnhookWindowsHookEx(hhk2)) {
					throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
				}
			}
		}
	}

	static void showWindow(String... args) {
		if (!User32.INSTANCE.EnumWindows((hwnd, data) -> {
			if (User32.INSTANCE.IsWindowVisible(hwnd)) {
				char[] text = new char[User32.INSTANCE.GetWindowTextLength(hwnd) + 1];
				int len = User32.INSTANCE.GetWindowText(hwnd, text, text.length);
				Arrays.asList(args).forEach((s) -> {
					if (Native.toString(Arrays.copyOfRange(text, 0, len)).contains(s)) {
						if (!User32.INSTANCE.ShowWindow(hwnd, WinUser.SW_MINIMIZE)) {
							throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
						}
					}
				});
			}
			return true;
		}, null)) {
			throw new Win32Exception(Kernel32.INSTANCE.GetLastError());
		}
	}

	public static void main(String[] args) {
		if (args.length == 0) {
			args = new String[] { "Microsoft​ Edge" };
		}
		new Cyberslacking(args);
	}
}